package com.mgee.netty.server.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import com.google.protobuf.Any;
import com.mgee.netty.server.netty.IoSession;
import com.mgee.netty.server.netty.SessionManager;
import com.mgee.netty.server.pojo.ChatUserInfo;
import com.mgee.netty.server.pojo.LobbyRoomInfo;
import com.mgee.netty.server.protobuf.ImProto;
import com.mgee.netty.server.protobuf.ImProto.ErrorResponse;
import com.mgee.netty.server.protobuf.ImProto.GameCommandType;
import com.mgee.netty.server.protobuf.ImProto.ImMsg;
import com.mgee.netty.server.protobuf.ImProto.RoomInfo;
import com.mgee.netty.server.protobuf.ImProto.SuccessResponse;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MessageBuilder {
	
	public static <T> ImMsg buildGameCommandMsg(String uid, GameCommandType type, 
			String content) {
    	try {
    		// 按照定义的数据结构，创建一个对象  
            ImProto.ImMsg.Builder imMsgBuilder = ImProto.ImMsg.newBuilder();
            ImProto.GameCommand.Builder gameNotificationBuilder = ImProto.GameCommand.newBuilder();
            
            gameNotificationBuilder.setType(type);
            gameNotificationBuilder.setContent(content);
            ImProto.GameCommand gameCommand = gameNotificationBuilder.build();  
            
            imMsgBuilder.setMsg(Any.pack(gameCommand));
            ImProto.ImMsg imMsg = imMsgBuilder.build();
            return imMsg;
    	}catch(Exception e) {
    		log.error("构建游戏命令消息体时发生异常：", e);
    		return null;
    	}
    }
 
    /**
     * 构建错误应答消息体
     * @param imMsg
     * @param errCode
     * @param errDesc
     * @return
     */
    public static ImMsg buildErrorResponse(ImMsg imMsg, int errCode, String errDesc) {
    	try {
    		
            ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
        	ErrorResponse.Builder errResponseBuilder = ErrorResponse.newBuilder();
        	errResponseBuilder.setErrCode(errCode);
        	errResponseBuilder.setErrMessage(errDesc);
        	ErrorResponse errResponse = errResponseBuilder.build();
//        	Any.Builder any = Any.newBuilder().mergeFrom(errResponse);
//            any.setTypeUrl(errResponse.getDescriptorForType().getFullName());
            imMsgBuilder.setMsg(Any.pack(errResponse));
            imMsgBuilder.setId(imMsg.getId());
            return imMsgBuilder.build();
    	}catch(Exception e) {
    		log.error("构建错误应答返回消息体时发生异常：", e);
    		return null;
    	}
    }
    
    public static ImMsg buildSuccessResponse(ImMsg imMsg, String message) {
    	try {
    		
            ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
        	SuccessResponse.Builder successResponseBuilder = SuccessResponse.newBuilder();
        	successResponseBuilder.setMessage(message);
        	SuccessResponse successResponse = successResponseBuilder.build();
//        	Any.Builder any = Any.newBuilder().mergeFrom(successResponse);
//            any.setTypeUrl(successResponse.getDescriptorForType().getFullName());
            imMsgBuilder.setMsg(Any.pack(successResponse));
            imMsgBuilder.setId(imMsg.getId());
            return imMsgBuilder.build();
    	}catch(Exception e) {
    		log.error("构建错误应答返回消息体时发生异常：", e);
    		return null;
    	}
    }
    
    public static LobbyRoomInfo roomInfoMsgToObject(RoomInfo roomInfo) {
    	
    	LobbyRoomInfo lobbyRoomInfo = new LobbyRoomInfo();
    	lobbyRoomInfo.setName(roomInfo.getRoomName());
    	lobbyRoomInfo.setMaxusers(Integer.parseInt(roomInfo.getRoomMaxusers()));
    	lobbyRoomInfo.setPeopleMember(Integer.parseInt(roomInfo.getRoomPeopleMomber()));
    	lobbyRoomInfo.setCurrentTaskIndex(roomInfo.getCurrentTaskIndex());
    	lobbyRoomInfo.setStatus(roomInfo.getRoomStatus());
    	lobbyRoomInfo.setOperatorsNumber(roomInfo.getOperatorsNumber());
    	lobbyRoomInfo.setViewersNumber(roomInfo.getViewersNumber());
    	lobbyRoomInfo.setUserWithRole(roomInfo.getUserWithRole());
    	Map<String, ChatUserInfo> usersMap = new ConcurrentHashMap<>();
    	for(String userName : roomInfo.getNamelistList()) {
    		IoSession userSession = SessionManager.userId2Sessions.get(userName);
    		if(userSession == null) continue;
    		
    		usersMap.put(userName, userSession.getUser());
    	}
    	lobbyRoomInfo.setUserlist(usersMap);
    	
		return lobbyRoomInfo;
    	
    }
    
    public static LobbyRoomInfo roomInfoMsgToObject(RoomInfo roomInfo, LobbyRoomInfo lobbyRoomInfo) {
    	
    	if(lobbyRoomInfo == null) return null;
    	
    	lobbyRoomInfo.setName(roomInfo.getRoomName());
    	lobbyRoomInfo.setMaxusers(Integer.parseInt(roomInfo.getRoomMaxusers()));
    	lobbyRoomInfo.setPeopleMember(Integer.parseInt(roomInfo.getRoomPeopleMomber()));
    	lobbyRoomInfo.setCurrentTaskIndex(roomInfo.getCurrentTaskIndex());
    	lobbyRoomInfo.setStatus(roomInfo.getRoomStatus());
    	lobbyRoomInfo.setOperatorsNumber(roomInfo.getOperatorsNumber());
    	lobbyRoomInfo.setViewersNumber(roomInfo.getViewersNumber());
    	lobbyRoomInfo.setUserWithRole(roomInfo.getUserWithRole());
    	Map<String, ChatUserInfo> usersMap = lobbyRoomInfo.getUserlist();
    	if(usersMap == null) {
    		usersMap = new ConcurrentHashMap<>();
    	}
    	
    	for(String userName : roomInfo.getNamelistList()) {
    		IoSession userSession = SessionManager.userId2Sessions.get(userName);
    		if(userSession == null) continue;
    		
    		usersMap.put(userName, userSession.getUser());
    	}
    	lobbyRoomInfo.setUserlist(usersMap);
    	
		return lobbyRoomInfo;
    	
    }
    
    public static RoomInfo buildRoomInfoMsg(LobbyRoomInfo lobbyRoomInfo) {
    	
    	RoomInfo.Builder roomInfoBuidler = RoomInfo.newBuilder();
    	
    	roomInfoBuidler.setRoomName(lobbyRoomInfo.getName());
    	roomInfoBuidler.setRoomMaxusers(String.valueOf(lobbyRoomInfo.getMaxusers()));
    	roomInfoBuidler.setRoomPeopleMomber(String.valueOf(lobbyRoomInfo.getPeopleMember()));
    	roomInfoBuidler.setRoomStatus(Optional.ofNullable(lobbyRoomInfo.getStatus()).orElse(0));
    	roomInfoBuidler.setCurrentTaskIndex(Optional.ofNullable(lobbyRoomInfo.getCurrentTaskIndex()).orElse(0));
    	roomInfoBuidler.setOperatorsNumber(Optional.ofNullable(lobbyRoomInfo.getOperatorsNumber()).orElse(0));
    	roomInfoBuidler.setViewersNumber(Optional.ofNullable(lobbyRoomInfo.getViewersNumber()).orElse(0));
    	roomInfoBuidler.setUserWithRole(Optional.ofNullable(lobbyRoomInfo.getUserWithRole()).orElse(""));
    	
    	if(lobbyRoomInfo.getUserlist() != null) {
    		for(ChatUserInfo userInfo : lobbyRoomInfo.getUserlist().values()) {
    			roomInfoBuidler.addNamelist(userInfo.getUid());
    		}
    	}
    	
		return roomInfoBuidler.build();
    	
    }
    
    public static List<RoomInfo> buildRoomInfoListMsg(Collection<LobbyRoomInfo> lobbyRoomInfos) {
    	
    	List<RoomInfo> results = new ArrayList<RoomInfo>(lobbyRoomInfos.size());
    	for(LobbyRoomInfo lobbyRoomInfo : lobbyRoomInfos) {
    		results.add(buildRoomInfoMsg(lobbyRoomInfo));
    	}
    	return results;
    }

}
